package org.deyang.tools.amazon.services;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.deyang.tools.amazon.exceptions.KeepaContentException;
import org.deyang.tools.amazon.pojos.AmazonResultEntry;
import org.deyang.tools.amazon.pojos.DealDetail;
import org.deyang.tools.amazon.pojos.PriceInformation;
import org.deyang.tools.amazon.pricetracker.KeepaPriceAnalyzer;
import org.deyang.tools.amazon.pricetracker.PriceAnalyzer;
import org.deyang.tools.amazon.utils.AmazonXMLProcessor;
import org.deyang.tools.amazon.utils.GlobalConstants;
import org.deyang.tools.amazon.utils.PriceUtils;
import org.deyang.tools.amazon.utils.SignedRequestsHelper;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;

public class ItemSearchService {
	
	private List<AmazonResultEntry> searchResultList = new ArrayList<AmazonResultEntry>();
	private static final Logger log = Logger.getLogger(ItemSearchService.class.getName());
	


    /*
     * The Item ID to lookup. The value below was selected for the US locale.
     * You can choose a different value if this value does not work in the
     * locale of your choice.
     */
    
    public List<AmazonResultEntry> doItemSearch(String keyword,String searchindex, String pageIndex){
        /*
         * Set up the signed requests helper 
         */
        SignedRequestsHelper helper = null;
        try {
            helper = SignedRequestsHelper.getInstance(GlobalConstants.ENDPOINT, GlobalConstants.AWS_ACCESS_KEY_ID, GlobalConstants.AWS_SECRET_KEY);
        } catch (Exception e) {
            e.printStackTrace();
            return searchResultList;
        }
        
//        Properties prop = System.getProperties(); 
//		prop.put("http.proxyHost","202.3.9.229"); 
//		prop.put("http.proxyPort","3128"); 

        Map<String, String> params = new HashMap<String, String>();
        params.put("Service", GlobalConstants.SERVICE_NAME);
        params.put("AssociateTag", GlobalConstants.ASSOCIATE_TAG);
        params.put("Operation", "ItemSearch");
        params.put("Keywords", keyword);
        if (!searchindex.equals("Blended")){
        	params.put("ItemPage", pageIndex);	
        }        
        //params.put("MinPercentageOff", "20");
        params.put("Condition", "New");
        //params.put("MerchantId", "Amazon");
        //params.put("Availability", "Available");
        params.put("SearchIndex", searchindex);
        params.put("ResponseGroup", "Medium,Offers,OfferFull");
        
        String requestUrl = helper.sign(params);
        
        try {
			URL url = new URL(requestUrl);
			log.info(requestUrl);
			
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        	DocumentBuilder db = dbf.newDocumentBuilder();
        	org.w3c.dom.Document domDoc = db.parse(url.openStream());
        	NodeList itemList = domDoc.getElementsByTagName("Item");
        	//initial Cache
        	MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
        	
        	
        	for (int i = 0; i < itemList.getLength(); i++){
        		Element itemElement = (Element) itemList.item(i);
        		
        		String asin = AmazonXMLProcessor.getDefaultChildNodeValue((Element) itemElement, "ASIN");
        		
        		AmazonResultEntry resultEntry = (AmazonResultEntry) syncCache.get(asin);
    			if (resultEntry != null){
    				searchResultList.add(resultEntry);
    				continue;
    			}
        		
        		resultEntry = new AmazonResultEntry();        		
        		resultEntry.setAsinValue(asin);
        		
        		//No cache record find, use normal way to check product deal
        		resultEntry.setLinkURL(AmazonXMLProcessor.getDefaultChildNodeValue(itemElement, "DetailPageURL"));
        		
        		Element mediumImageElement = AmazonXMLProcessor.getDefaultChildNode(itemElement, "MediumImage");
        		resultEntry.setMediumImageURL(AmazonXMLProcessor.getDefaultChildNodeValue(mediumImageElement, "URL"));
        		
        		Element arrtElement = AmazonXMLProcessor.getDefaultChildNode(itemElement, "ItemAttributes");
        		resultEntry.setOrignialProductTitle(AmazonXMLProcessor.getDefaultChildNodeValue(arrtElement, "Title"));
        		
        		//Check whether it is a deal
        		PriceInformation pi = PriceUtils.getCurrentLowPrice(itemElement, true);
        		String itemFormat = AmazonXMLProcessor.getDefaultChildNodeValue(AmazonXMLProcessor.getDefaultChildNode(itemElement, "ItemAttributes"),"Format");
        		String itemBinding = AmazonXMLProcessor.getDefaultChildNodeValue(AmazonXMLProcessor.getDefaultChildNode(itemElement, "ItemAttributes"),"Binding");
        		
        		resultEntry.setItemBinding(itemBinding);
        		
//        		resultEntry.setDealRate(0);
//    			resultEntry.setFormattedPrice(pi.getAvailablePrice());
        		PriceAnalyzer kpt;
        		if (!itemFormat.equals("Kindle eBook")){
        			//In case it is not a ebook product, use keepa to check its price status
        			try {
						kpt = new KeepaPriceAnalyzer(resultEntry.getAsinValue(),pi);
						if (kpt.isDeal(30)){
		        			DealDetail dd = kpt.getDealDetail();
		        			if (dd.isAmazonDeal()){
		        				resultEntry.setDealRate(dd.getDealRate());
		        				resultEntry.setFormattedPrice(pi.getAmazonPrice());
		        			}else if (dd.isMarketDeal()){
		        				resultEntry.setDealRate(dd.getDealRate());
		        				resultEntry.setFormattedPrice(pi.getThirdPartyPrice());
		        			}
		        		}else{
		        			resultEntry.setDealRate(0);
		        			resultEntry.setFormattedPrice(pi.getAvailablePrice());
		        		}
					} catch (KeepaContentException e) {
						resultEntry.setDealRate(0);
						resultEntry.setFormattedPrice(pi.getAvailablePrice());
					}	
        		}else{
        			//In case it is a kindle book, currently don't check deal status for it.
        			resultEntry.setDealRate(0);
        			resultEntry.setFormattedPrice(pi.getAvailablePrice());
        		}
        		
        		syncCache.put(asin, resultEntry,Expiration.byDeltaSeconds(3600));
        		searchResultList.add(resultEntry);
        	}			
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
        return searchResultList;
    }



    
}
